package com.shenganyuan.smac.common;

import android.support.annotation.NonNull;
import android.text.TextUtils;

import com.oklib.utils.Logger.Logger;
import com.oklib.utils.network.common.GsonUtil;
import com.shenganyuan.smac.App;
import com.shenganyuan.smac.common.data.ApiResult;

import java.io.EOFException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;

import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;

/**
 * Created by Damon.Han on 2018/5/23 0023.
 * 处理token失效等
 *
 * @author Damon
 */
public class SmacResponseInterceptor implements Interceptor {
    private static final Charset UTF8 = Charset.forName("UTF-8");

    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {
        return process(chain);
    }

    private Response process(Chain chain) throws IOException {
        Request request = chain.request();
        List<String> tokens = request.url().queryParameterValues("token");
        if (tokens != null && tokens.size() > 0) {
            String tok = tokens.get(0);
            if (TextUtils.isEmpty(tok)) {
                Logger.e(request.url() == null ? "URL为空" : request.url().toString() + "<-- Token 为空");
                return processAccessTokenExpired(chain, request);
            }
        }
        Response response = chain.proceed(request);
        ResponseBody responseBody = response.body();
        if (responseBody == null) {
            return response;
        }
        BufferedSource source = responseBody.source();
        source.request(Long.MAX_VALUE); // Buffer the entire body.
        Buffer buffer = source.buffer();
        Charset charset = UTF8;
        MediaType contentType = responseBody.contentType();
        if (contentType != null) {
            charset = contentType.charset(UTF8);
        }
        if (charset == null) {
            return response;
        }
        if (!isPlaintext(buffer)) {
            Logger.e("<-- END HTTP (binary " + buffer.size() + "-byte body omitted)");
            return response;
        }

        String bodyString = buffer.clone().readString(charset);
        if (!TextUtils.isEmpty(bodyString)) {
            ApiResult apiResult = GsonUtil.gson().fromJson(bodyString, ApiResult.class);
            if (apiResult != null && !TextUtils.isEmpty(apiResult.getResult())) {
                if (apiResult.getResult().equalsIgnoreCase(SmacResponseCode.ACCESS_TOKEN_NULL) || apiResult.getResult().equalsIgnoreCase(SmacResponseCode.ACCESS_TOKEN_EXPIRED)) {
                    return processAccessTokenExpired(chain, request);
                }
            }
        }
        return response;
    }

    static boolean isPlaintext(Buffer buffer) {
        try {
            Buffer prefix = new Buffer();
            long byteCount = buffer.size() < 64 ? buffer.size() : 64;
            buffer.copyTo(prefix, 0, byteCount);
            for (int i = 0; i < 16; i++) {
                if (prefix.exhausted()) {
                    break;
                }
                int codePoint = prefix.readUtf8CodePoint();
                if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) {
                    return false;
                }
            }
            return true;
        } catch (EOFException e) {
            return false; // Truncated UTF-8 sequence.
        }
    }

    /**
     * token过期
     *
     * @param chain
     * @param request
     * @return
     */
    private Response processAccessTokenExpired(Chain chain, Request request) {
        App.restartApp();
        return null;
    }

    private boolean isText(MediaType mediaType) {
        if (mediaType == null) {
            return false;
        }
        if (mediaType.type() != null && mediaType.type().equals("text")) {
            return true;
        }
        String subtype = mediaType.subtype();
        if (subtype != null) {
            subtype = subtype.toLowerCase();
            if (subtype.contains("x-www-form-urlencoded") ||
                    subtype.contains("json") ||
                    subtype.contains("xml") ||
                    subtype.contains("html")) {
                return true;
            }
        }
        return false;
    }


}
